/****************************************************************************
 * Chariott - Continuous Integration Testing Tool
 * Zaid Mohsin
 * The University of York
 * 2012/2013
 * MSc in Information Technology
 * All rights reserved.
 ****************************************************************************/
package chariott.configuration;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import chariott.main.Main;
import chariott.testing.RunItem;
import chariott.testing.TestCase;
import chariott.testing.TestSequence;

/**
 * class that fetches the test cases and sequences specified by the developers
 * and translates them into Item to Run
 * 
 * @author Zaid
 * 
 */
public class XMLTestResolver {

	private File testConfigFile;

	public XMLTestResolver(File f) {
		this.testConfigFile = f;
	}

	/**
	 * method to transform the TestCases and Sequences from test configurations
	 * XML to RunItem ArrayList to be used by tool
	 * 
	 * @return ArrayList RunItems to distribute
	 */
	public ArrayList<RunItem> fetchRunItems() {

		ArrayList<RunItem> myRunItems = new ArrayList<RunItem>();

		try {

			SAXBuilder sb = new SAXBuilder();
			Document doc = sb.build(testConfigFile);

			Element rootNode = doc.getRootElement();

			List list = rootNode.getChildren();

			for (int i = 0; i < list.size(); i++) {

				Element node = (Element) list.get(i);

				// check if test case is correct
				if (node.getChildren().size() == 0
						&& !node.getParentElement().getName()
								.equals("sequence")) {

					if (node.getAttribute("name") == null)
						System.out
								.println("specify a name for your test cases in the test configuration file");
					else if (node.getAttribute("weight") == null)
						System.out
								.println("specify a weight value for your test cases in the test configuration file");
					else
						myRunItems.add(parseTestCase(node));

				} else if (node.getName().equals("sequence")) {
					// check if sequences has test cases children
					if (node.getChildren().size() > 0) {
						List<Element> childNode = node.getChildren();
						TestSequence myTestSequence = new TestSequence();
						for (Element e : childNode)
							myTestSequence.addCase(parseTestCase(e));

						myRunItems.add(myTestSequence);
					}

				}
			}
		}

		catch (IOException io) {
			Main.logger.error(io.getMessage());
		} catch (JDOMException jdomex) {
			Main.logger.error(jdomex.getMessage());
		}

		return myRunItems;
	}

	private TestCase parseTestCase(Element e) {

		TestCase newCase = new TestCase(e.getAttributeValue("name"),
				Double.parseDouble(e.getAttributeValue("weight")));

		return newCase;
	}

	public ArrayList<TestCase> fetchTestCases() {
		ArrayList<TestCase> myTestCases = new ArrayList<TestCase>();

		SAXBuilder sb = new SAXBuilder();
		Document doc;
		try {
			doc = sb.build(testConfigFile);
			Element rootNode = doc.getRootElement();

			List<Element> list = rootNode.getChildren();

			for (Element e : list) {
				if (e.getName().equals("testcase"))
					myTestCases.add(new TestCase(e.getAttributeValue("name"),
							Double.parseDouble(e.getAttributeValue("weight"))));
				else {
					List<Element> sequenceList = e.getChildren();
					for (Element t : sequenceList) {
						myTestCases.add(new TestCase(t
								.getAttributeValue("name"), Double
								.parseDouble(t.getAttributeValue("weight"))));
					}
				}
			}

		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return myTestCases;
	}

}
